/*
 * Copyright 2014 Davy Maddelein.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.compomics.pepshell.view.dataloading;

import com.compomics.pepshell.FaultBarrier;
import com.compomics.pepshell.model.AnnotatedFile;
import com.compomics.pepshell.model.SeparatedValueExperimentMetadata;
import com.compomics.pepshell.model.enums.PossibleMetaDataAnnotationsEnum;
import com.compomics.pepshell.view.components.JFileChooserWithMemory;
import java.awt.event.KeyEvent;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.Collections;
import java.util.List;
import java.awt.Cursor;
import java.util.Map;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

/**
 * @author Davy Maddelein
 */
public class MetaDataProviderDialog extends javax.swing.JDialog {

    private DefaultListModel<AnnotatedFile> model = new DefaultListModel<>();
    private AnnotatedFile reference;

    /**
     * Creates new form MetaDataProviderDialog
     */
    public MetaDataProviderDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
    }

    @Override
    public void setVisible(boolean visible) {
        extraMetaDataAnnotatorPanel1.clearMetaData();
        super.setVisible(visible);
    }

    public void setFilesToAnnotate(List<File> files) {
        model.clear();
        for (File aFile : files) {
            AnnotatedFile replacement = new AnnotatedFile(aFile.getAbsolutePath());
            model.addElement(replacement);
        }
        filesToAnnotateList.setModel(model);
    }

    public void setFilesToAnnotate(File referenceFile, List<File> files) {
        model.clear();
        reference = new AnnotatedFile(referenceFile.getAbsolutePath());
        model.addElement(reference);
        for (File aFile : files) {
            model.addElement(new AnnotatedFile(aFile.getAbsolutePath()));
        }
        filesToAnnotateList.setModel(model);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        filesToAnnotateList = new javax.swing.JList<AnnotatedFile>();
        multipleExperimentsCheckbox = new javax.swing.JCheckBox();
        addInfoToFilesButton = new javax.swing.JButton();
        commitDataButton1 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        extraMetaDataAnnotatorPanel1 = new com.compomics.pepshell.view.dataloading.ExtraMetaDataAnnotatorPanel();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenuItem2 = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("provide meta data for experiment parsing");
        setPreferredSize(new java.awt.Dimension(920, 565));
        addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                formKeyTyped(evt);
            }
        });

        jPanel1.setBackground(new java.awt.Color(255, 255, 255));
        jPanel1.setAutoscrolls(true);
        jPanel1.setMinimumSize(new java.awt.Dimension(645, 455));
        jPanel1.setPreferredSize(new java.awt.Dimension(950, 460));

        jScrollPane2.setViewportView(filesToAnnotateList);

        multipleExperimentsCheckbox.setText("multiple experiments per file");
        multipleExperimentsCheckbox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                multipleExperimentsCheckboxActionPerformed(evt);
            }
        });

        addInfoToFilesButton.setText("accept metadata");
        addInfoToFilesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addInfoToFilesButton1ActionPerformed(evt);
            }
        });

        commitDataButton1.setText("accept and finalize metadata gathering");
        commitDataButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                commitDataButton1ActionPerformed(evt);
            }
        });

        jScrollPane1.setBackground(new java.awt.Color(255, 255, 255));
        jScrollPane1.setBorder(null);
        jScrollPane1.setMinimumSize(new java.awt.Dimension(525, 80));
        jScrollPane1.setPreferredSize(new java.awt.Dimension(525, 80));

        extraMetaDataAnnotatorPanel1.setMaximumSize(new java.awt.Dimension(32767, 32767));
        extraMetaDataAnnotatorPanel1.setMinimumSize(new java.awt.Dimension(200, 80));
        extraMetaDataAnnotatorPanel1.setPreferredSize(new java.awt.Dimension(200, 80));
        extraMetaDataAnnotatorPanel1.addContainerListener(new java.awt.event.ContainerAdapter() {
            public void componentAdded(java.awt.event.ContainerEvent evt) {
                extraMetaDataAnnotatorPanel1ComponentAdded(evt);
            }
            public void componentRemoved(java.awt.event.ContainerEvent evt) {
                extraMetaDataAnnotatorPanel1ComponentRemoved(evt);
            }
        });
        jScrollPane1.setViewportView(extraMetaDataAnnotatorPanel1);

        jButton1.setText("cancel");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jButton2.setText("clear metadata");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jButton3.setText("select all experiments");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                            .addGap(36, 36, 36)
                            .addComponent(multipleExperimentsCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                            .addGap(1285, 1285, 1285))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(jPanel1Layout.createSequentialGroup()
                                            .addGap(35, 35, 35)
                                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                                    .addGroup(jPanel1Layout.createSequentialGroup()
                                                            .addComponent(jButton1)
                                                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                                            .addComponent(commitDataButton1))
                                                    .addGroup(jPanel1Layout.createSequentialGroup()
                                                            .addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 171, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                            .addGap(18, 18, 18)
                                                            .addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 142, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                            .addGap(50, 50, 50)
                                                            .addComponent(addInfoToFilesButton, javax.swing.GroupLayout.PREFERRED_SIZE, 141, javax.swing.GroupLayout.PREFERRED_SIZE))))
                                    .addGroup(jPanel1Layout.createSequentialGroup()
                                            .addGap(18, 18, 18)
                                            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 549, javax.swing.GroupLayout.PREFERRED_SIZE)))
                            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                            .addGap(20, 20, 20)
                        .addComponent(multipleExperimentsCheckbox)
                            .addGap(22, 22, 22)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 343, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(addInfoToFilesButton)
                            .addComponent(jButton2)
                            .addComponent(jButton3))
                            .addGap(14, 14, 14)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jButton1)
                                .addComponent(commitDataButton1))
                            .addGap(0, 11, Short.MAX_VALUE))
                    .addComponent(jScrollPane2))
                .addContainerGap())
        );

        jMenu1.setText("Annotation Files");

        jMenuItem1.setText("save annotations");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem1);

        jMenuItem2.setText("load annotations");
        jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem2ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem2);

        jMenuBar1.add(jMenu1);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 795, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(0, 0, 0)
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 507, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jCheckBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox1ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jCheckBox1ActionPerformed

    private void addInfoToFilesButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addInfoToFilesButton1ActionPerformed
        // TODO add your handling code here:
        filesToAnnotateList.getSelectedValuesList().stream().forEach((aFile) -> {
            aFile.addAnnotationsToFile(extraMetaDataAnnotatorPanel1.getAllAnnotations());
        });
        StringBuilder builder = new StringBuilder("annotations added to files:\n");
        filesToAnnotateList.getSelectedValuesList().stream().forEach(aFile -> {
            builder.append(aFile.getName()).append("\n");
        });
        JOptionPane.showMessageDialog(this, builder.toString());
    }//GEN-LAST:event_addInfoToFilesButton1ActionPerformed

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        extraMetaDataAnnotatorPanel1.clearMetaData();
    }//GEN-LAST:event_jButton2ActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        //remove file data
        this.dispose();
    }//GEN-LAST:event_jButton1ActionPerformed

    private void extraMetaDataAnnotatorPanel1ComponentAdded(java.awt.event.ContainerEvent evt) {//GEN-FIRST:event_extraMetaDataAnnotatorPanel1ComponentAdded
        extraMetaDataAnnotatorPanel1.repaint();
        jScrollPane1.scrollRectToVisible(evt.getComponent().getBounds());
        this.pack();
    }//GEN-LAST:event_extraMetaDataAnnotatorPanel1ComponentAdded

    private void extraMetaDataAnnotatorPanel1ComponentRemoved(java.awt.event.ContainerEvent evt) {//GEN-FIRST:event_extraMetaDataAnnotatorPanel1ComponentRemoved
        extraMetaDataAnnotatorPanel1.repaint();
        jScrollPane1.scrollRectToVisible(evt.getComponent().getBounds());
        this.pack();
    }//GEN-LAST:event_extraMetaDataAnnotatorPanel1ComponentRemoved

    private void commitDataButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_commitDataButton1ActionPerformed
        // TODO add your handling code here:
        //very not clean
        addInfoToFilesButton1ActionPerformed(null);
        this.setVisible(false);
    }//GEN-LAST:event_commitDataButton1ActionPerformed

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
        // TODO add your handling code here:
        SeparatedValueExperimentMetadata data = extraMetaDataAnnotatorPanel1.getAllAnnotations();
        JFileChooserWithMemory chooser = JFileChooserWithMemory.getInstance();
        chooser.setMultiSelectionEnabled(false);
        int state = chooser.showSaveDialog(this);
        if (state == JFileChooser.APPROVE_OPTION) {
            try {
                try (FileWriter writer = new FileWriter(chooser.getSelectedFile())) {
                    for (Map.Entry<PossibleMetaDataAnnotationsEnum, String> anEntry : data.getMetaDataAsMap().entrySet()) {
                        writer.append(anEntry.getKey().name() + " = " + anEntry.getValue() + "\n");
                    }
                    writer.flush();
                }
            } catch (IOException ex) {
                FaultBarrier.getInstance().handleException(ex);
            }
        }
    }//GEN-LAST:event_jMenuItem1ActionPerformed

    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed
        // TODO add your handling code here:
        JFileChooserWithMemory chooser = JFileChooserWithMemory.getInstance();
        chooser.setMultiSelectionEnabled(false);
        int state = chooser.showOpenDialog(this);
        if (state == JFileChooser.APPROVE_OPTION) {
            this.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
            try {
                LineNumberReader reader = new LineNumberReader(new FileReader(chooser.getSelectedFile()));
                String aString = reader.readLine();
                while (aString != null) {
                    String[] annotation = aString.split(" = ");
                    extraMetaDataAnnotatorPanel1.setAnnotation(annotation[0], annotation[1]);
                    aString = reader.readLine();
                }
            } catch (IOException ioe) {
                FaultBarrier.getInstance().handleException(ioe);
            }
            this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }
    }//GEN-LAST:event_jMenuItem2ActionPerformed

    private void formKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_formKeyTyped
        // TODO add your handling code here:
        if (evt.getKeyCode() == KeyEvent.VK_A && evt.isControlDown()) {
            filesToAnnotateList.setSelectionInterval(0, filesToAnnotateList.getModel().getSize());
        }
    }//GEN-LAST:event_formKeyTyped

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
        // TODO add your handling code here:
        filesToAnnotateList.getSelectionModel().setSelectionInterval(0, filesToAnnotateList.getModel().getSize()-1);
        
    }//GEN-LAST:event_jButton3ActionPerformed

    public AnnotatedFile getReferenceExperimentFile() {
        return reference;

    }

    public List<AnnotatedFile> getFiles() {

        return Collections.list(model.elements());
    }

    private void multipleExperimentsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:

    }


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addInfoToFilesButton;
    private javax.swing.JButton commitDataButton1;
    private com.compomics.pepshell.view.dataloading.ExtraMetaDataAnnotatorPanel extraMetaDataAnnotatorPanel1;
    private javax.swing.JList<AnnotatedFile> filesToAnnotateList;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JCheckBox multipleExperimentsCheckbox;
    // End of variables declaration//GEN-END:variables
}
